
package com.scalar.chiptrack.sales.actions;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.operations.LotNumberQtyAndDateOut;
import com.scalar.chiptrack.operations.LotQuantity;
import com.scalar.chiptrack.operations.LotReservation;
import com.scalar.chiptrack.operations.process.FinishedGoods;
import com.scalar.chiptrack.operations.process.dao.FinishedGoodsDAO;
import com.scalar.chiptrack.operations.process.dao.LotDAO;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.sales.LineItem;
import com.scalar.chiptrack.sales.dao.CustomerDAO;
import com.scalar.chiptrack.sales.dao.SalesDAO;
import com.scalar.chiptrack.sales.dao.SalesOrderDAO;
import com.scalar.chiptrack.sales.forms.OrdersForm;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.utils.StringUtils;


/**
 * Implementation of <strong>Action</strong> that gives customers list,
 * search with customer name, create sales order
 *
 * @author Kesava Kumar Achanala
 * @version $Revision: 1.1.1.1 $ $Date: 2006/12/11 23:43:18 $
 */

public final class ScheduleOrdersAction extends ChipTrackAction {


    public static final int CONSTANT_TIME_FOR_MANUAL_TRANSACTIONS = 5;
    private static final String ACTION_NAME = "/scheduling.do" ;  // Added by Basha (08/08/2003)

    // ----------------------------------------------------- Instance Variables
        ArrayList lineItemList  = new ArrayList();

        //Hash Map for messages
        //static HashMap errors = null;

        //static HttpServletRequest request = null;
        //HttpSession session  = request.getSession ();


    // --------------------------------------------------------- Public Methods


    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     * Return an <code>ActionForward</code> instance describing where and how
     * control should be forwarded, or <code>null</code> if the response has
     * already been completed.
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception Exception if business logic throws an exception
     */
    public ActionForward execute (ActionMapping mapping,
				 ActionForm form,
				 HttpServletRequest request,
				 HttpServletResponse response) throws Exception {

        HttpSession session = request.getSession();
        HashMap errors = new HashMap();

        User user = (User) session.getAttribute (SessionKeys.USER_KEY);
        if (user == null) {
            session.setAttribute (SessionKeys.SOURCE_PAGE_KEY,  ACTION_NAME  + "?" + request.getQueryString());
            return (mapping.findForward ("login"));
        }

        // Extract attributes and parameters we will need
        OrdersForm subform = (OrdersForm) form;
        String action = request.getParameter("action");

        // Validate the request parameters specified by the user
        //HashMap errors = new HashMap();
       // System.out.println("Action is  = " + action);
        if(action == null)
            request.setAttribute("showList", "FALSE"); //Not to show the list by default

        request.setAttribute("customerList",CustomerDAO.getAllCustomerNames());
        request.setAttribute("productList",loadMarketingProducts());
        // Prabhanjan (06 Apr 2004)
        request.setAttribute ( "years", SalesOrderDAO.getYearList () );

        if("SearchOrders".equals(action))
        {

            //here using the property utils we can get the form value
            String customerId = BeanUtils.getSimpleProperty ( form, "customerId" );
            String marketingPartNo = BeanUtils.getSimpleProperty ( form, "marketingPartNo" );
            String salesOrderNo = BeanUtils.getSimpleProperty ( form, "salesOrderNo" ); // added by prabhanjan on 28th october 2003
            String booking_year = BeanUtils.getSimpleProperty ( form, "year" ); // added by prabhanjan on 06 Apr 2004
            // System.out.println("Customer ID = " + customerId + " , part no = " + marketingPartNo);

            // added by prabhanjan on 28th October 2003
            if ( customerId != null )
            {
                customerId = customerId.trim ();
            }
            if ( marketingPartNo != null )
            {
                marketingPartNo = marketingPartNo.trim ();
            }
            if ( salesOrderNo != null )
            {
                salesOrderNo = salesOrderNo.trim ();
            }
            // Prabhanjan (06 Apr 2004)
            if(booking_year != null)
            {
                booking_year = booking_year.trim ();
            }

            // modified by prabhanjan
            lineItemList = SalesDAO.loadOrdersForScheduling ( customerId, marketingPartNo, salesOrderNo, booking_year );

            if(lineItemList.size() == 0)
            {
                errors.put( ERROR_SALES_ORDERS_NOT_FOUND_ORDER_SCHEDULING, null );
            }
            else
            {
                //Show the pendingList only when it searched
                request.setAttribute("showList", "TRUE");
            }

            request.setAttribute("lineItemList", lineItemList);
            request.setAttribute("scheduling",subform);
            //System.out.println("List of orders size is = " + lineItemList.size());
        }
        else if((action != null) && (action.equals("ScheduleOrder")))
        {

            DBTransaction dbTransaction = null;
            boolean success = false;

            try {
               //Begine Transaction
               dbTransaction = DBTransaction.getInstance();
               dbTransaction.begin();

               //Get the lineItems..
               String[] lineItemIds = request.getParameterValues("lineItemId");
               String[] scheduleDates = request.getParameterValues("scheduleDate");
              // System.out.println("LineItemId " + lineItemIds);
              // System.out.println("Schedule Dates " + scheduleDates);
               //Approve the salesOrderId
               SalesDAO.scheduleOrders(dbTransaction,lineItemIds,scheduleDates,user);

               success = true;

            }
            catch (ScalarException se)
            {
                errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_LOADING_SCHEDULE_ORDERS);
                errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could Not Load Schedule Orders ");
                session.setAttribute( SessionKeys.ERROR_REPORT, se );
            }
            finally {
               // Rollback or Commit the Transaction
               if (success == true) {
                    dbTransaction.commit();
                    errors.put("Orders scheduled successfully", "");
               }
               else
               {
                    dbTransaction.rollback();
                    errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_LOADING_SCHEDULE_ORDERS);
                    errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                    session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could Not Schedule Orders ");
                    session.setAttribute( SessionKeys.ERROR_REPORT, null );
                }
            }

            return (mapping.findForward("success"));
        }

        else if((action != null) && (action.equals("ShowInventory"))) {

            /*
            //Added for Kits
            ArrayList list = SalesOrderDAO.loadAllKitPartNumbers(request.getParameter("marketingPartNo"));
            for (int i=0; i<list.size(); i++)
            {
                String partNumber = (String)list.get(i);
                request.setAttribute("inventoryDetails"+i, SalesDAO.loadInventory(partNumber));
                request.setAttribute("scheduleUnits"+i,SalesDAO.loadAllScheduleUnits(partNumber));
            }
            request.setAttribute("kitSize",list.size()+"");
            */ // *** not for brecis ***
            //till here

            request.setAttribute("inventroryDetails", SalesDAO.loadInventory(request.getParameter("marketingPartNo")));
            request.setAttribute("scheduleUnits",SalesDAO.loadAllScheduleUnits(request.getParameter("marketingPartNo")));

            //added by kumar to show the lot detials by day for shippable units
            request.setAttribute("lotDetails",SalesDAO.loadAllLotDetailsByWeek(request.getParameter("marketingPartNo")));
            request.setAttribute("scheduleOrderDetails",SalesDAO.loadAllBackLogByWeek(request.getParameter("marketingPartNo")));

            // added by Balaram.. remove old lineItem from session.. dec 26, 2002
            session.removeAttribute ("lineItem");


            return (mapping.findForward ("showInventory"));
        }

        else if ("reschedule".equalsIgnoreCase (action)) {

            try {
                String mktPartNumber = request.getParameter("marketingPartNo");
                String lineItemNumber = request.getParameter ("lineItemNo");
                String salesOrderId = request.getParameter ("salesOrderId");
                String requestedScheduleDate = request.getParameter("scheduleDate");

                // Added by Prabhanjan on 16th November 2003
                // to indicate whether the schedule date is saved or not - for refreshing Order Scheduling screen if saved.
                String isScheduleDateSaved = request.getParameter ( "isScheduleDateSaved" );
                if ( ( isScheduleDateSaved != null ) && ( isScheduleDateSaved.equals ( "true" ) ) )
                {
                    request.setAttribute ( "isScheduleDateSaved", "true" );
                }


                if ((requestedScheduleDate == null) || (requestedScheduleDate.trim().length() == 0)) {
                    requestedScheduleDate = request.getParameter("requestedDate");
                }

                int requestedQty = Integer.parseInt (request.getParameter("quantity"));

                LineItem lineItem = reScheduleLineItem (lineItemNumber, salesOrderId, mktPartNumber, requestedScheduleDate, requestedQty);
                lineItem.setQuantity (requestedQty);

                session.setAttribute ("lineItem", lineItem);

                HashMap info = new LinkedHashMap();
                Iterator remarks = lineItem.getRemarks();
                while (remarks.hasNext()) {
                    info.put (remarks.next(), null);
                }

                if(lineItem.getLotReservationList().size()>0) { //Condition added by kumar
                info.put ("Requested Schedule Date: " + requestedScheduleDate + ", System Suggested Date: " + lineItem.getSuggScheduleDate(), null);

                info.put ("NOTE: These lots will not be reserved until save this schedule date", null);
                } else { //Added by Kumar
                    info.put("Requested Schedule Date: " + requestedScheduleDate + ", System Suggested Date: Not able to suggest the date due to lack of wafers " , null);
                }
                request.setAttribute (SessionKeys.INFO_MESSAGES, info);

                request.setAttribute ("inventroryDetails", SalesDAO.loadInventory (mktPartNumber));
                request.setAttribute ("scheduleUnits",SalesDAO.loadAllScheduleUnits (mktPartNumber));

                //added by kumar to show the lot detials by day for shippable units
                request.setAttribute("lotDetails",SalesDAO.loadAllLotDetailsByWeek(request.getParameter("marketingPartNo")));
                request.setAttribute("scheduleOrderDetails",SalesDAO.loadAllBackLogByWeek(request.getParameter("marketingPartNo")));


            }
            catch (ScalarException se)
            {
                errors = new HashMap();
                errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_RESCHEDULING_SALES_ORDER);
                errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error:Could not get re-schedule the LineItem ");
                session.setAttribute( SessionKeys.ERROR_REPORT, se );
                request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);

                //se.printStackTrace();
            }

            return (mapping.findForward ("showInventory"));
        }

        else if ("releaseLots".equalsIgnoreCase (action)) {

            try {
                String lineItemNumber = request.getParameter ("lineItemNo");
                String salesOrderId = request.getParameter ("salesOrderId");


                LotDAO.releaseReservedLots (null /*DBTransaction*/, lineItemNumber, salesOrderId);

                request.setAttribute ("inventroryDetails", SalesDAO.loadInventory (request.getParameter ("marketingPartNo")));
                request.setAttribute ("scheduleUnits", SalesDAO.loadAllScheduleUnits (request.getParameter ("marketingPartNo")));

                //added by kumar to show the lot detials by day for shippable units
                request.setAttribute("lotDetails",SalesDAO.loadAllLotDetailsByWeek(request.getParameter("marketingPartNo")));
                request.setAttribute("scheduleOrderDetails",SalesDAO.loadAllBackLogByWeek(request.getParameter("marketingPartNo")));

                // Added by Prabhanjan on 16th November 2003
                // to indicate whether the schedule date is saved or not - for refreshing order schedule search screen if saved.
                request.setAttribute ( "isScheduleDateSaved", "true" );

                HashMap info = new HashMap();
                info.put ("Lots has been released successfully", null);
                request.setAttribute (SessionKeys.INFO_MESSAGES, info);

            }
            catch (ScalarException se)
            {
                errors = new HashMap();
                errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_RELEASING_LOTS);
                errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
                session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could Not Release Lots ");
                session.setAttribute( SessionKeys.ERROR_REPORT, se );
                request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);

                //se.printStackTrace();
            }

            session.removeAttribute ("lineItem");
            return (mapping.findForward ("showInventory"));
        }
        else if ("saveScheduleDate".equalsIgnoreCase (action)) {

            boolean success = false;
            DBTransaction dbTransaction = null;

            HashMap info = new HashMap();
            request.setAttribute (SessionKeys.INFO_MESSAGES, info);

            try {
                // Start transaction
                dbTransaction = DBTransaction.getInstance();
                dbTransaction.begin();

                String lineItemNumber = request.getParameter ("lineItemNo");
                String salesOrderId = request.getParameter ("salesOrderId");
                String scheduleDate = request.getParameter("scheduleDate");
                String systemSuggDate = request.getParameter("systemSuggDate");
                if (systemSuggDate == null) systemSuggDate = "";

                LineItem lineItem = (LineItem) session.getAttribute ("lineItem");


                // Step 1
                // Release Old Lots
                LotDAO.releaseReservedLots (dbTransaction, lineItemNumber, salesOrderId);

                // Step 2
                // Reserve lots only if the system suggested date and schedule date are same
                if ((scheduleDate != null) && (scheduleDate.trim().equalsIgnoreCase(systemSuggDate.trim()))) {

                    if (lineItem != null) {
                        ArrayList lotReservationList = lineItem.getLotReservationList();
                       // System.out.println("lot reservation total = " + lotReservationList.size());

                        if (lotReservationList != null) {
                            LotDAO.saveLotReservationList (dbTransaction, lotReservationList.iterator());
                        }
                    }
                }
                else {
                    info.put ("Schedule Date: <b>" + scheduleDate + "</b> differed from System Suggested Date: <b>" + systemSuggDate + "</b>.", null);
                    info.put ("All previously reserved lots (if any) are released and No new Lots are reserved", null);
                }

                // Step 3
                // Update System Suggested Date and schedule Date
                SalesOrderDAO.updateLineItemSuggestedDateAndSystemDate (dbTransaction, lineItemNumber, salesOrderId, systemSuggDate, scheduleDate);

                // Added by Prabhanjan on 16th November 2003
                // to indicate whether the schedule date is saved or not for refreshing order schedule search screen if saved.
                request.setAttribute ( "isScheduleDateSaved", "true" );

                info.put ("System Suggested Date and Schedule Date are updated successfully", null);
                success = true;
            }

            catch (ScalarException se) {
                errors = new HashMap();
                errors.put ("Internal Server Error", "Could not update Schedule Date");
                request.setAttribute (SessionKeys.ERROR_MESSAGES, errors);

                se.printStackTrace();
            }

            finally {

                if (success == true) {
                    dbTransaction.commit();
                }
                else {
                    if (dbTransaction != null) {
                        dbTransaction.rollback();
                    }
                }
            }

            request.setAttribute ("inventroryDetails", SalesDAO.loadInventory (request.getParameter ("marketingPartNo")));
            request.setAttribute ("scheduleUnits",SalesDAO.loadAllScheduleUnits (request.getParameter ("marketingPartNo")));

            //added by kumar to show the lot detials by day for shippable units
            request.setAttribute("lotDetails",SalesDAO.loadAllLotDetailsByWeek(request.getParameter("marketingPartNo")));
            request.setAttribute("scheduleOrderDetails",SalesDAO.loadAllBackLogByWeek(request.getParameter("marketingPartNo")));

            session.removeAttribute ("lineItem");
            return (mapping.findForward ("showInventory"));
        }

        // Report any errors we have discovered back to the original form
        if(!errors.isEmpty()) {
            request.setAttribute(SessionKeys.MESSAGES, errors);
        }

        //Please look at this return later(Where do we need this retrurned) ????
        return (mapping.findForward("success"));
    }


    public static ArrayList loadOrdersForScheduling (String customerId, String marketingPartNo) throws ScalarException {
        return getLineItemListWithSuggestedDates (SalesDAO.loadOrdersForScheduling (customerId, marketingPartNo, null, null));
    }

    public static ArrayList getLineItemListWithSuggestedDates (int salesOrderId) throws ScalarException {
        return getLineItemListWithSuggestedDates (SalesOrderDAO.loadOrderLineItems (salesOrderId));
    }


    private static LineItem reScheduleLineItem (String lineItemNumber, String salesOrderId, String mktPartNumber, String requestedScheduleDate, int requestedQty) throws ScalarException {

        LineItem lineItem = null;
        Date now = new Date();



        boolean success = false;
        DBTransaction dbTransaction = null;

        try {
            // Start transaction
            dbTransaction = DBTransaction.getInstance();
            dbTransaction.begin();


            // Step 1
            // Load Line Item
            lineItem = SalesOrderDAO.loadOrderLineItem (lineItemNumber, salesOrderId);


            // Step 2
            // Get reserved lot qty for this lineItem
            HashMap reservedLotQtyByWeekMap = SalesDAO.getReservedLotQuantityByLineItem (lineItemNumber, salesOrderId);


            // Step 3
            // Get Delta - including this line Item reserved lots
            HashMap deltaShippableUnits = SalesDAO.loadDeltaScheduleUnits (mktPartNumber);


            // Step 4
            // Get Delta - excluding this lineItem's reservation
            deltaShippableUnits = addReservedQtyToDelta (deltaShippableUnits, reservedLotQtyByWeekMap);


            // Step 4
            // Get new Schedule Date
            Date requestedDate = StringUtils.format (requestedScheduleDate.trim());
            //Deduct 5 days from requested date for shipping
            Calendar calDate = new GregorianCalendar();
            calDate.setTime(requestedDate);
            calDate.add (Calendar.DAY_OF_WEEK, -5);
            requestedDate = calDate.getTime();

            long daysToRequestedDate = ((requestedDate.getTime() - now.getTime())/(1000*60*60*24));
            if (daysToRequestedDate < 0) daysToRequestedDate = 0;   // ASAP
            long weekNumber = (daysToRequestedDate/7) + 1;

            int transitTimeFromFabToFG = SalesDAO.getTransitTimeForStep ("FAB", mktPartNumber, CONSTANT_TIME_FOR_MANUAL_TRANSACTIONS);
            long transitTimeFromFabWeekNumber = (transitTimeFromFabToFG/7) + 1;

            //System.out.println ("Requested quantity: " + requestedQty + ", requested Date: " + lineItem.getRequestDate() + ", Requested Schedule Date: " + requestedDate);
            //System.out.println ("week number: " + weekNumber);
            String systemSuggestedDate = null;

            if (daysToRequestedDate >= transitTimeFromFabToFG) {

                lineItem.setSuggScheduleDate (StringUtils.formatDateToString (requestedDate, null));
                lineItem.setScheduleDate (StringUtils.formatDateToString (requestedDate, null));

                lineItem.setRemarks (LineItem.REMARK_WAFERS_CAN_BE_STARTED);

               // System.out.println ("Wafers can be started to meet the required date");
            }
            //else { this is commented because for boards it is giving null pointer exception...so now user can reserve the lots
                    //eventhough daystorequested is greater than the transit time from fab to fg -- kumar

                int qty = 0;
                int currQty = 0;
                boolean hasRequiredQty = false;
                Iterator processStepTypeNameItr = null;
                String processStepTypeName = null;
                LotQuantity psLotQuantity = null;
                LotQuantity reservedPSLotQuantity = null;
                LinkedHashMap reservedPSLotQuantityMap = null;
                HashMap processStepQuantityMap = null;
                ArrayList lotReservationList = new ArrayList();
                LinkedHashMap reservedLotQuantityByWeek = new LinkedHashMap();
                ArrayList lotNumberQuantityAndExpDateList = null;
                Calendar sysSuggCal = null;

                Set ProcessStepTypeNamesSet = ProductDao.getForwardProcessStepTypeNamesPartNumber (mktPartNumber);


                for (int j= (int) weekNumber; j>=1; j--) {
                   // System.out.println ("Week: " + j);
                    //if the required qty matched already then end the loop, as previous check is ending the while loop -- kumar
                    if (hasRequiredQty == true) {
                            break;
                    }

                    processStepQuantityMap = (HashMap) deltaShippableUnits.get (j+"");
                    if (processStepQuantityMap == null) {
                        continue;
                    }

                    processStepTypeNameItr = ProcessStepTypeNamesSet.iterator();

                    reservedPSLotQuantityMap = new LinkedHashMap();
                    while (processStepTypeNameItr.hasNext()) {

                        processStepTypeName = (String) processStepTypeNameItr.next();
                        //System.out.println ("ProcessStep Name: " + processStepTypeName);

                        psLotQuantity = (LotQuantity) processStepQuantityMap.get (processStepTypeName);
                        if ((psLotQuantity == null) || (psLotQuantity.getQuantity() <= 0)) {
                            continue;
                        }

                        reservedPSLotQuantity = new LotQuantity();
                        reservedPSLotQuantity.setProcessStepName (processStepTypeName);
                        reservedPSLotQuantityMap.put (processStepTypeName, reservedPSLotQuantity);

                        currQty = psLotQuantity.getQuantity();

                       // System.out.println ("Week: " + j + " -> Step: " +  psLotQuantity.getProcessStepName() + ", Quantity: " + (qty+currQty) + "requested qty = " + requestedQty);

                        if ((qty+currQty) <= requestedQty) {
                            psLotQuantity.setQuantity(0);
                            processStepQuantityMap.remove (processStepTypeName);

                            reservedPSLotQuantity.setQuantity (currQty);

                            lotNumberQuantityAndExpDateList = psLotQuantity.getLotNumberQtyList();
                            reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                            qty += currQty;
                            //System.out.println ("qty = " + qty);
                        }
                        else {
                            psLotQuantity.setQuantity (qty+currQty-requestedQty);
                            reservedPSLotQuantity.setQuantity (requestedQty-qty);

                            lotNumberQuantityAndExpDateList = reserveRequiredQtyFromLots (requestedQty-qty, psLotQuantity.getLotNumberQtyList());
                            reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                            if (now.compareTo (requestedDate) > 0) {
                                sysSuggCal = Calendar.getInstance();
                                sysSuggCal.add (Calendar.DAY_OF_YEAR, j*7);
                                systemSuggestedDate = StringUtils.formatDateToString (sysSuggCal.getTime());
                            }
                            else {
                                //systemSuggestedDate = StringUtils.formatDateToString (requestedDate, null);
                                systemSuggestedDate = StringUtils.formatDateToString (calDate.getTime(), null);
                            }

                           // System.out.println ("-> week = " + j + ", system sugg date = " + systemSuggestedDate);

                            hasRequiredQty = true;
                        }

                        // Add the details to reservation lot
                        lotReservationList = addToLotReservationList (lotNumberQuantityAndExpDateList, lineItem.getLineItemNo(), lineItem.getSalesOrderId(), lotReservationList);
                        //System.out.println("Has Required is = " + hasRequiredQty);
                        if (hasRequiredQty == true) {
                            break;
                        }
                    }

                    reservedLotQuantityByWeek.put (j+"", reservedPSLotQuantityMap);
                }

                // If there is not enough qty, start adding quantity from the week after the requestedQtyWeek
                if (hasRequiredQty == false) {

                    lineItem.setRemarks (LineItem.REMARK_NOT_ENOUGH_QTY_TO_MEET_GIVE_DATE + requestedScheduleDate + ", trying best possible future date..");

                   // System.out.println ("Not enough quantity, starting from week after the requested date");
                    for (int j= (int) (weekNumber+1); j<transitTimeFromFabWeekNumber; j++) {
                        //if the required qty matched already then end the loop, as previous check is ending the while loop -- kumar
                        if (hasRequiredQty == true) {
                            break;
                        }

                        processStepQuantityMap = (HashMap) deltaShippableUnits.get (j+"");
                        if (processStepQuantityMap == null) {
                            continue;
                        }

                        processStepTypeNameItr = ProcessStepTypeNamesSet.iterator();

                        reservedPSLotQuantityMap = new LinkedHashMap();
                        while (processStepTypeNameItr.hasNext()) {

                            processStepTypeName = (String) processStepTypeNameItr.next();
                            //System.out.println ("ProcessStep Name: " + processStepTypeName);

                            psLotQuantity = (LotQuantity) processStepQuantityMap.get (processStepTypeName);
                            if ((psLotQuantity == null) || (psLotQuantity.getQuantity() <= 0)) {
                                continue;
                            }

                            reservedPSLotQuantity = new LotQuantity();
                            reservedPSLotQuantity.setProcessStepName (processStepTypeName);
                            reservedPSLotQuantityMap.put (processStepTypeName, reservedPSLotQuantity);

                            currQty = psLotQuantity.getQuantity();

                            //System.out.println ("Week: " + j + " -> Step: " +  psLotQuantity.getProcessStepName() + ", Quantity: " + psLotQuantity.getQuantity());
                            if ((qty+currQty) <= requestedQty) {
                                psLotQuantity.setQuantity(0);
                                processStepQuantityMap.remove (processStepTypeName);

                                reservedPSLotQuantity.setQuantity (currQty);

                                lotNumberQuantityAndExpDateList = psLotQuantity.getLotNumberQtyList();
                                reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                                qty += currQty;
                                //System.out.println ("qty = " + qty);
                            }
                            else {
                                psLotQuantity.setQuantity (qty+currQty-requestedQty);
                                reservedPSLotQuantity.setQuantity (requestedQty-qty);

                                lotNumberQuantityAndExpDateList = reserveRequiredQtyFromLots (requestedQty-qty, psLotQuantity.getLotNumberQtyList());
                                reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                                //if (now.compareTo (requestedDate) > 0) {
                                //    systemSuggestedDate = StringUtils.formatDateToString (new Date (((((j-1)*7) + 6)*(1000*60*60*24)) + System.currentTimeMillis()), null);
                                //}
                                //else {
                                //   systemSuggestedDate = StringUtils.formatDateToString (requestedDate, null);
                                //}
                                sysSuggCal = Calendar.getInstance();
                                sysSuggCal.add (Calendar.DAY_OF_YEAR, j*7);
                                systemSuggestedDate = StringUtils.formatDateToString (sysSuggCal.getTime());
                                //System.out.println ("week = " + j + ", system sugg date = " + systemSuggestedDate);

                                hasRequiredQty = true;
                            }

                            // Add the details to reservation lot
                            lotReservationList = addToLotReservationList (lotNumberQuantityAndExpDateList, lineItem.getLineItemNo(), lineItem.getSalesOrderId(), lotReservationList);

                            if (hasRequiredQty == true) {
                                break;
                            }
                        }

                        reservedLotQuantityByWeek.put (j+"", reservedPSLotQuantityMap);
                    }

                }

                if (hasRequiredQty == true) {
                    lineItem.setSuggScheduleDate (systemSuggestedDate);
                    lineItem.setScheduleDate (systemSuggestedDate);

                    lineItem.setRemarks (LineItem.REMARK_GOT_REQUIRED_QUANTITY + systemSuggestedDate);
                }
                else {
                    // not enough quantity
                    // Start from fab

                    Calendar suggestedDate = Calendar.getInstance();
                    suggestedDate.add (Calendar.DAY_OF_MONTH, transitTimeFromFabToFG);

                    lineItem.setSuggScheduleDate (StringUtils.formatDateToString (suggestedDate.getTime(), null));
                    lineItem.setScheduleDate (StringUtils.formatDateToString (suggestedDate.getTime(), null));

                    //Added by kumar..by adding this you cannot save with -ve units
                    lineItem.setSuggScheduleDate (null);
                    lineItem.setScheduleDate(null);
                    reservedLotQuantityByWeek.clear();
                    lotReservationList.clear();
                    int quantityLeft = requestedQty - qty;
                    //For calaulating the wafers needed
                    int wafersNeeded = SalesDAO.loadWafersNeededToStart(dbTransaction, mktPartNumber,quantityLeft);
                    //System.out.println("Wafers Needed " + wafersNeeded);
                    String waferComment = null;
                    if (wafersNeeded == -1)
                        waferComment = "<BR>    System not able to calculate the wafers to be started";
                    else
                        waferComment = "<BR>    Wafers Needed to meet this Quantity : " + wafersNeeded;
                    //till here kumar
                    lineItem.setRemarks (LineItem.REMARK_NOT_ENOUGH_QTY_WAFERS_TO_BE_STARTED + " Requested Qty: " + requestedQty + ", Found: " + qty + waferComment );

                   // System.out.println ("Not enough quantity, Wafers has to be started");
                }

                lineItem.setReservedLotQtyByWeekMap (reservedLotQuantityByWeek);
                lineItem.setLotReservationList (lotReservationList);

            //}

            success = true;
        }


        catch (ScalarException se)
        {
            //errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_RESCHEDULING_SALES_ORDER);
            //errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
            //session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error:  Exception while re-scheduling the lineItem");
            //session.setAttribute( SessionKeys.ERROR_REPORT, se );

            System.out.println (" (lineItem# " + lineItemNumber + ", salesOrder ID: " + salesOrderId + ") -->\n" + se);
            throw se;
        }


        finally {

            if (success == true) {
                dbTransaction.commit();
            }
            else {
                if (dbTransaction != null) {
                    dbTransaction.rollback();
                }
            }
        }

        return lineItem;
    }

    public static ArrayList getLineItemListWithSuggestedDates (ArrayList lineItemList) throws ScalarException {

        if ((lineItemList == null) || (lineItemList.size() == 0)) {
            return new ArrayList();
        }

        ArrayList lotReservationList = new ArrayList();

        Set ProcessStepTypeNamesSet = null;
        HashMap partNumberStepNamesMap = new HashMap();
        HashMap deltaShippableUnits = null;
        HashMap deltaShippableUnitsMap = new HashMap();
        String mktPartNumber = null;
        Date requestedDate = null;
        int requestedQty = 0;
        Date now = new Date();
        LineItem lineItem = null;
        LinkedHashMap reservedLotQuantityByWeek = null;
        ArrayList lotNumberQuantityAndExpDateList = null;


        int lineItemListSize = lineItemList.size();
        for (int i=0; i<lineItemListSize; i++) {

            reservedLotQuantityByWeek = new LinkedHashMap();

            lineItem = (LineItem) lineItemList.get (i);
           // System.out.println ("line item ID: " + lineItem.getLineItemId());

            String suggDate = lineItem.getSuggScheduleDateWithoutSubstitutables();
            if (suggDate != null) {

               // System.out.println ("LineItem ID: " + lineItem.getLineItemId() + " - scheduled date is calculated: " + suggDate);

                lineItem.setSuggScheduleDate (suggDate);
                lineItem.setScheduleDate (suggDate);

                continue;   // Sugg schedule date - Already calculated
            }


            String scheduleDate = lineItem.getScheduleDate();
            if ((scheduleDate != null) && (scheduleDate.trim().length() != 0)) {
                //System.out.println ("LineItem ID: " + lineItem.getLineItemId() + " - already scheduled, schedule date = " + scheduleDate);

                if ((suggDate == null) || (suggDate.trim().length() == 0)) {
                    lineItem.setSuggScheduleDate (scheduleDate);
                }

                continue;   // Already scheduled
            }


            requestedDate = StringUtils.format (lineItem.getRequestDate());
            requestedQty = lineItem.getQuantity();

            mktPartNumber = lineItem.getMarketingPartNo();

            ProcessStepTypeNamesSet = (Set) partNumberStepNamesMap.get(mktPartNumber);
            if (ProcessStepTypeNamesSet == null) {
                ProcessStepTypeNamesSet = ProductDao.getForwardProcessStepTypeNamesPartNumber (mktPartNumber);
                partNumberStepNamesMap.put (mktPartNumber, ProcessStepTypeNamesSet);
            }

            deltaShippableUnits = (HashMap) deltaShippableUnitsMap.get (mktPartNumber);
            if (deltaShippableUnits == null) {
                deltaShippableUnits = SalesDAO.loadDeltaScheduleUnits (mktPartNumber);
                deltaShippableUnitsMap.put (mktPartNumber, deltaShippableUnits);
            }

            long daysToRequestedDate = ((requestedDate.getTime() - now.getTime())/(1000*60*60*24));
            if (daysToRequestedDate < 0) daysToRequestedDate = 0;   // ASAP
            long weekNumber = (daysToRequestedDate/7) + 1;

            int transitTimeFromFabToFG = SalesDAO.getTransitTimeForStep ("FAB", mktPartNumber, CONSTANT_TIME_FOR_MANUAL_TRANSACTIONS);
            long transitTimeFromFabWeekNumber = (transitTimeFromFabToFG/7) + 1;

            //System.out.println ("Requested quantity: " + requestedQty + ", requested Date: " + requestedDate);

            //if (now.compareTo (requestedDate) >= 0) {    // requested Date already passed
                //System.out.println ("LineItem ID: " + lineItem.getLineItemId() + " requested date: " + requestedDate + " - date passed");
            //    continue;
            //}

            String systemSuggestedDate = null;

            if (daysToRequestedDate >= transitTimeFromFabToFG) {

                lineItem.setSuggScheduleDate (StringUtils.formatDateToString (requestedDate, null));
                lineItem.setScheduleDate (StringUtils.formatDateToString (requestedDate, null));

                lineItem.setRemarks (LineItem.REMARK_WAFERS_CAN_BE_STARTED);

               // System.out.println ("Wafers can be started to meet the required date");
            }
            else {

                int qty = 0;
                int currQty = 0;
                boolean hasRequiredQty = false;
                Iterator processStepTypeNameItr = null;
                String processStepTypeName = null;
                LotQuantity psLotQuantity = null;
                LotQuantity reservedPSLotQuantity = null;
                LinkedHashMap reservedPSLotQuantityMap = null;
                HashMap processStepQuantityMap = null;
                Calendar sysSuggCal = null;

                for (int j= (int) weekNumber; j>=1; j--) {
                    //System.out.println ("Week: " + j);

                    processStepQuantityMap = (HashMap) deltaShippableUnits.get (j+"");
                    if (processStepQuantityMap == null) {
                        continue;
                    }

                    processStepTypeNameItr = ProcessStepTypeNamesSet.iterator();

                    reservedPSLotQuantityMap = new LinkedHashMap();
                    while (processStepTypeNameItr.hasNext()) {

                        processStepTypeName = (String) processStepTypeNameItr.next();
                        //System.out.println ("ProcessStep Name: " + processStepTypeName);

                        psLotQuantity = (LotQuantity) processStepQuantityMap.get (processStepTypeName);
                        if ((psLotQuantity == null) || (psLotQuantity.getQuantity() <= 0)) {
                            continue;
                        }

                        reservedPSLotQuantity = new LotQuantity();
                        reservedPSLotQuantity.setProcessStepName (processStepTypeName);
                        reservedPSLotQuantityMap.put (processStepTypeName, reservedPSLotQuantity);

                        currQty = psLotQuantity.getQuantity();

                        //System.out.println ("Week: " + j + " -> Step: " +  psLotQuantity.getProcessStepName() + ", Quantity: " + psLotQuantity.getQuantity());
                        if ((qty+currQty) <= requestedQty) {
                            psLotQuantity.setQuantity(0);
                            processStepQuantityMap.remove (processStepTypeName);

                            reservedPSLotQuantity.setQuantity (currQty);

                            lotNumberQuantityAndExpDateList = psLotQuantity.getLotNumberQtyList();
                            reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                            qty += currQty;
                            //System.out.println ("qty = " + qty);
                        }
                        else {
                            psLotQuantity.setQuantity (qty+currQty-requestedQty);
                            reservedPSLotQuantity.setQuantity (requestedQty-qty);

                            lotNumberQuantityAndExpDateList = reserveRequiredQtyFromLots (requestedQty-qty, psLotQuantity.getLotNumberQtyList());
                            reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                            if (now.compareTo (requestedDate) > 0) {
                                sysSuggCal = Calendar.getInstance();
                                sysSuggCal.add (Calendar.DAY_OF_YEAR, j*7);
                                systemSuggestedDate = StringUtils.formatDateToString (sysSuggCal.getTime());

                                //systemSuggestedDate = StringUtils.formatDateToString (new Date (((((j-1)*7) + 6)*(1000*60*60*24)) + System.currentTimeMillis()), null);
                            }
                            else {
                                systemSuggestedDate = StringUtils.formatDateToString (requestedDate, null);
                            }

                            //System.out.println ("week = " + j + ", system sugg date = " + systemSuggestedDate);

                            hasRequiredQty = true;
                        }

                        // Add the details to reservation lot
                        lotReservationList = addToLotReservationList (lotNumberQuantityAndExpDateList, lineItem.getLineItemNo(), lineItem.getSalesOrderId(), lotReservationList);

                        if (hasRequiredQty == true) {
                            break;
                        }
                    }

                    reservedLotQuantityByWeek.put (j+"", reservedPSLotQuantityMap);
                }

                // If there is not enough qty, start adding quantity from the week after the requestedQtyWeek
                if (hasRequiredQty == false) {

                    lineItem.setRemarks (LineItem.REMARK_NOT_ENOUGH_QTY_TO_MEET_GIVE_DATE + requestedDate + ", trying best possible future date..");

                    for (int j= (int) (weekNumber+1); j<transitTimeFromFabWeekNumber; j++) {
                        //System.out.println ("Week: " + j);

                        processStepQuantityMap = (HashMap) deltaShippableUnits.get (j+"");
                        if (processStepQuantityMap == null) {
                            continue;
                        }

                        processStepTypeNameItr = ProcessStepTypeNamesSet.iterator();

                        reservedPSLotQuantityMap = new LinkedHashMap();
                        while (processStepTypeNameItr.hasNext()) {

                            processStepTypeName = (String) processStepTypeNameItr.next();
                            //System.out.println ("ProcessStep Name: " + processStepTypeName);

                            psLotQuantity = (LotQuantity) processStepQuantityMap.get (processStepTypeName);
                            if ((psLotQuantity == null) || (psLotQuantity.getQuantity() <= 0)) {
                                continue;
                            }

                            reservedPSLotQuantity = new LotQuantity();
                            reservedPSLotQuantity.setProcessStepName (processStepTypeName);
                            reservedPSLotQuantityMap.put (processStepTypeName, reservedPSLotQuantity);

                            currQty = psLotQuantity.getQuantity();

                            //System.out.println ("Week: " + j + " -> Step: " +  psLotQuantity.getProcessStepName() + ", Quantity: " + psLotQuantity.getQuantity());
                            if ((qty+currQty) <= requestedQty) {
                                psLotQuantity.setQuantity(0);
                                processStepQuantityMap.remove (processStepTypeName);

                                reservedPSLotQuantity.setQuantity (currQty);

                                lotNumberQuantityAndExpDateList = psLotQuantity.getLotNumberQtyList();
                                reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                                qty += currQty;
                                //System.out.println ("qty = " + qty);
                            }
                            else {
                                psLotQuantity.setQuantity (qty+currQty-requestedQty);
                                reservedPSLotQuantity.setQuantity (requestedQty-qty);

                                lotNumberQuantityAndExpDateList = reserveRequiredQtyFromLots (requestedQty-qty, psLotQuantity.getLotNumberQtyList());
                                reservedPSLotQuantity.setLotNumberQtyList (lotNumberQuantityAndExpDateList);

                                //if (now.compareTo (requestedDate) > 0) {
                                //  systemSuggestedDate = StringUtils.formatDateToString (new Date (((((j-1)*7) + 6)*(1000*60*60*24)) + System.currentTimeMillis()), null);
                                //}
                                //else {
                                //    systemSuggestedDate = StringUtils.formatDateToString (requestedDate, null);
                                //}

                                //System.out.println ("week = " + j + ", system sugg date = " + systemSuggestedDate);
                                sysSuggCal = Calendar.getInstance();
                                sysSuggCal.add (Calendar.DAY_OF_YEAR, j*7);
                                systemSuggestedDate = StringUtils.formatDateToString (sysSuggCal.getTime());

                                hasRequiredQty = true;
                            }

                            // Add the details to reservation lot
                            lotReservationList = addToLotReservationList (lotNumberQuantityAndExpDateList, lineItem.getLineItemNo(), lineItem.getSalesOrderId(), lotReservationList);

                            if (hasRequiredQty == true) {
                                break;
                            }
                        }

                        reservedLotQuantityByWeek.put (j+"", reservedPSLotQuantityMap);
                    }

                }

                if (hasRequiredQty == true) {
                    lineItem.setSuggScheduleDate (systemSuggestedDate);
                    lineItem.setScheduleDate (systemSuggestedDate);

                    lineItem.setRemarks (LineItem.REMARK_GOT_REQUIRED_QUANTITY);
                }
                else {
                    // not enough quantity
                    // Start from fab

                    Calendar suggestedDate = Calendar.getInstance();
                    suggestedDate.add (Calendar.DAY_OF_MONTH, transitTimeFromFabToFG);

                    lineItem.setSuggScheduleDate (StringUtils.formatDateToString (suggestedDate.getTime(), null));
                    lineItem.setScheduleDate (StringUtils.formatDateToString (suggestedDate.getTime(), null));

                    lineItem.setRemarks (LineItem.REMARK_NOT_ENOUGH_QTY_WAFERS_TO_BE_STARTED + " Requested Qty: " + requestedQty + ", Found: " + qty);
                    lotReservationList = new ArrayList();
                   // System.out.println ("Not enough quantity, Wafers has to be started");
                }

                lineItem.setReservedLotQtyByWeekMap (reservedLotQuantityByWeek);
                lineItem.setLotReservationList (lotReservationList);

            }   //-------------------------------------------------------------------------------

        }

        /*
        // Lets see what we have reserved for these line items
        Iterator lineItems = lineItemList.iterator();
        LineItem tempLineItem = null;
        HashMap reservedQtyByWeekMap = null;
        Iterator weekNumbers = null;
        String weekNumber = null;
        HashMap reservedProcessStepLotQty = null;
        Iterator processStepNames = null;
        String processStepName = null;
        LotQuantity reservedLotQty = null;

        while (lineItems.hasNext()) {

            tempLineItem = (LineItem) lineItems.next();

            reservedQtyByWeekMap = tempLineItem.getReservedLotQtyByWeek();
            if ((reservedQtyByWeekMap == null) || (reservedQtyByWeekMap.isEmpty() == true)) {
                continue;
            }

            System.out.println ("\n>>-------> Lot Reservation Matrix for Line Item Number: " + tempLineItem.getLineItemNo() + "\n");

            weekNumbers = reservedQtyByWeekMap.keySet().iterator();

            while (weekNumbers.hasNext()) {
                weekNumber = (String) weekNumbers.next();
                System.out.println ("Week: " + weekNumber);

                reservedProcessStepLotQty = (HashMap) reservedQtyByWeekMap.get (weekNumber);

                processStepNames = reservedProcessStepLotQty.keySet().iterator();
                while (processStepNames.hasNext()) {
                    processStepName = (String) processStepNames.next();
                    reservedLotQty = (LotQuantity) reservedProcessStepLotQty.get (processStepName);

                    System.out.println (reservedLotQty);
                }
            }
        }*/

        // Lot reservation List
        //Iterator lotReservations = lotReservationList.iterator();
        //while (lotReservations.hasNext()) {
        //    System.out.println ("--> " + lotReservations.next() + "\n");
        //}


        boolean success = false;
        DBTransaction dbTransaction = null;
        try {

            // Start transaction
            dbTransaction = DBTransaction.getInstance();
            dbTransaction.begin();

            // Step 1
            // Save Lot Reservation List
            LotDAO.saveLotReservationList (dbTransaction, lotReservationList.iterator());

            // Step 2
            // Update Line items suggested date
            SalesOrderDAO.updateLineItemSuggestedDates (dbTransaction, lineItemList.iterator());

            success = true;
        }

		// Escalate the exception to the caller method - Balaram, Aug 11, 2003

        //catch (ScalarException se)
        //{
             //errors.put(ERROR_INTERNAL_SERVER_ERROR, ERROR_IN_LOADING_LINE_ITEMS_WITH_SUGGESTED_DATE);
             //errors.put( ERROR_MESSAGE_CONTACT_SYS_ADMN, null );
             //session.setAttribute( SessionKeys.ERROR_REPORT_SUBJECT, " Error: Could Not Load Line Items with Suggested Date");
             //session.setAttribute( SessionKeys.ERROR_REPORT, se );
        //}

        finally {
            if (success == true) {
                dbTransaction.commit();
            }
            else {
                if (dbTransaction != null) {
                    dbTransaction.rollback();
                }
            }

        }

        return lineItemList;

    }


    private static ArrayList reserveRequiredQtyFromLots (int requiredQty, ArrayList lotNumberQuantityAndExpDateList) {

        ArrayList reservedLotNumberQuantityAndExpDateList = new ArrayList();

        Iterator keys = lotNumberQuantityAndExpDateList.iterator();
        LotNumberQtyAndDateOut key = null;

        int qty = 0;
        int totalQty = 0;
        int remainingQty = 0;

        while (keys.hasNext()) {

            key = (LotNumberQtyAndDateOut) keys.next();
            qty = key.getQuantity();

       // System.out.println ("Setting " + key.getLotNumber() + " to qty: " + qty);
            //System.out.println ("required qty = " + requiredQty + ", qty = " + qty + ", totalQty = " + totalQty);

            if ((totalQty+qty) <= requiredQty) {
                reservedLotNumberQuantityAndExpDateList.add (new LotNumberQtyAndDateOut (key.getLotNumber(), qty, key.getExpectedDateOut()));
                totalQty = totalQty + qty;
                //System.out.println ("Setting " + lotNumber + " to qty: " + qty);
            }
            else {
                remainingQty = (requiredQty-totalQty);

                if (remainingQty != 0) {
                    reservedLotNumberQuantityAndExpDateList.add (new LotNumberQtyAndDateOut (key.getLotNumber(), remainingQty, key.getExpectedDateOut()));
                }

                //System.out.println ("Setting " + lotNumber + " to remainingQty: " + remainingQty);
                break;
            }
        }

        return reservedLotNumberQuantityAndExpDateList;
    }


    private static ArrayList addToLotReservationList (ArrayList lotNumberQuantityAndExpDateList, int lineItemNo, int salesOrderId, ArrayList lotReservationList) {

        if (lotReservationList == null) lotReservationList = new ArrayList();

        if ((lotNumberQuantityAndExpDateList == null) || (lotNumberQuantityAndExpDateList.isEmpty() == true)) {
            return lotReservationList;
        }

        Iterator keys = lotNumberQuantityAndExpDateList.iterator();
        LotNumberQtyAndDateOut key = null;
        LotReservation lotReservation = null;

        while (keys.hasNext()) {

            key = (LotNumberQtyAndDateOut) keys.next();
            //System.out.println("Lot Number = " + key.getLotNumber() + " Lot Qty = " + key.getQuantity());
            lotReservation = new LotReservation (lineItemNo,
                                                   salesOrderId,
                                                   key.getLotNumber(),
                                                   key.getQuantity(),
                                                   key.getExpectedDateOut().toString(),
                                                   null /* Process Step Type Name */,
                                                   "SYSTEM"  /* Reserved By */,
                                                   new java.sql.Date (System.currentTimeMillis()).toString());   /* Lot Quantity Reserved Date */

            lotReservationList.add (lotReservation);

            //System.out.println ("lot Number: " + key.getLotNumber() + ", quantity = " + key.getQuantity() + ", Exp Date Out = " + key.getExpectedDateOut());
        }

        return lotReservationList;
    }



    private static HashMap addReservedQtyToDelta (HashMap lotQtyByWeekMap1, HashMap lotQtyByWeekMap2) {

        if (lotQtyByWeekMap1 == null) {
            return null;
        }

        if ((lotQtyByWeekMap2 == null) || (lotQtyByWeekMap2.isEmpty() == true)) {
            return lotQtyByWeekMap1;
        }

        Iterator steps = null;
        HashMap psLotQtyMap1 = null;
        HashMap psLotQtyMap2 = null;
        LotQuantity psLotQty1 = null;
        LotQuantity psLotQty2 = null;
        String psName = null;
        int qty1 = 0;
        int qty2 = 0;

        for (int i=1; i<=13; i++) {
            psLotQtyMap1 = (HashMap) lotQtyByWeekMap1.get (i+"");
            psLotQtyMap2 = (HashMap) lotQtyByWeekMap2.get (i+"");

            if (psLotQtyMap2 == null) {
                continue;
            }

            if (psLotQtyMap1 == null) {

                if (psLotQtyMap2 != null) {
                    lotQtyByWeekMap1.put (i+"", psLotQtyMap2);
                }

                continue;
            }

            steps = psLotQtyMap1.keySet().iterator();

            while (steps.hasNext()) {
                psName = (String) steps.next();

                psLotQty1 = (LotQuantity) psLotQtyMap1.get (psName);
                psLotQty2 = (LotQuantity) psLotQtyMap2.get (psName);

                if ((psLotQty1 == null) && (psLotQty2 != null)) {
                    psLotQty1 = psLotQty2;
                }
                else if ((psLotQty1 != null) && (psLotQty2 != null)) {
                    psLotQty1.setQuantity(psLotQty1.getQuantity() + psLotQty2.getQuantity());
                }

            }
        }


        return lotQtyByWeekMap1;
    }


    public static void main (String[] args) throws ScalarException {
        getLineItemListWithSuggestedDates (32);
    }

    private static ArrayList loadMarketingProducts() throws Exception
    {
        ArrayList parts = new ArrayList();
        Iterator list = FinishedGoodsDAO.loadAllFinishedGoods().iterator();
        // Modified by Prabhanjan (15 Apr 2004)
        //Iterator list = SalesOrderDAO.loadOnlyFinishedGoodsHavingCustomerPartNos(0).iterator();


        parts.add(new org.apache.struts.util.LabelValueBean("All Products","0"));
        while(list.hasNext())
        {
            FinishedGoods product = (FinishedGoods)list.next();
            // added by prabhanjan on 28th october 2003
            if ( product.getManufacturingPartNo ().equals ( "---- BOARD -----" ) )
            {
                product.setProductId ( -1 );
            }
            if ( product.getManufacturingPartNo ().equals ( "---- KIT -----" ) )
            {
                product.setProductId ( -2 );
            }
            // till here prabhanjan
            parts.add(new org.apache.struts.util.LabelValueBean(product.getManufacturingPartNo(),product.getProductId()+""));
        }

        return parts;
    }
}

